﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Xps.Packaging;
using MSFforAgileSoftwareDevelopmentv50;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using MicrosoftVisualStudioScrum10;
using WorkItemReportInterface;
using MessageBox = System.Windows.MessageBox;

namespace TaskCardCreator
{
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow : Window
  {
    private ProjectInfo projInfo;
    private WorkItemStore workItemStoreService;
    private WorkItemTypeCollection wiTypes;

    public ObservableCollection<WorkItem> WorkItems { get; set; }

    public MainWindow()
    {
      WorkItems = new ObservableCollection<WorkItem>();

      InitializeComponent();

      listView.DataContext = this;
      queries.SelectionChanged += queries_SelectionChanged;
    }

    private void selectProjectButton_Click(object sender, RoutedEventArgs e)
    {
      using (TeamProjectPicker tpp = new TeamProjectPicker(TeamProjectPickerMode.SingleProject, false))
      {
        DialogResult result = tpp.ShowDialog();

        if (result == System.Windows.Forms.DialogResult.OK)
        {
          projInfo = tpp.SelectedProjects[0];
          workItemStoreService = tpp.SelectedTeamProjectCollection.GetService<WorkItemStore>();
          foreach (Project project in workItemStoreService.Projects)
          {
              if (project.Name == projInfo.Name)
              {
                  wiTypes = project.WorkItemTypes;
                  break;
              }
              wiTypes = null;
          }
          queries.BuildQueryTree(workItemStoreService.Projects[tpp.SelectedProjects[0].Name].QueryHierarchy, projInfo.Name);
        }
      }
    }

    void queries_SelectionChanged(string queryString)
    {
      WorkItems.Clear();

      var q = new Query(workItemStoreService, queryString);
      if (q.IsLinkQuery)
      {
        var queryResults = q.RunLinkQuery();
        foreach (WorkItemLinkInfo i in queryResults)
        {
          var wi = workItemStoreService.GetWorkItem(i.TargetId);
          WorkItems.Add(wi);
        }
      }
      else
      {
        var queryResults = q.RunQuery();
        foreach (WorkItem workitem in queryResults)
        {
          WorkItems.Add(workitem);
        }
      }

      listView.SelectAll();
    }

    private enum ProjectTypes
    {
      MicrosoftVisualStudioScrum10,
      MSFforAgileSoftwareDevelopmentv50,
      Unknown
    }

    /// <summary>
    /// Try to detect process template. This is done by looking at specific work item types
    /// </summary>
    /// <returns>Project type</returns>
    private ProjectTypes ProjectType()
    {
      if (wiTypes == null)
        return ProjectTypes.Unknown;

      if (wiTypes.Count == 0)
        return ProjectTypes.Unknown;

      // Only the Scrum process template has this type
      if (wiTypes.Contains("Product Backlog Item") == true)
        return ProjectTypes.MicrosoftVisualStudioScrum10;

      // Only the MSF for Agile process template has this type
      if (wiTypes.Contains("User Story") == true)
        return ProjectTypes.MSFforAgileSoftwareDevelopmentv50;

      return ProjectTypes.Unknown;
    }

    private bool GenerateAndSaveReport(string path)
    {
      IWorkItemReport reportTemplate = null;
      switch(ProjectType())
      {
        case ProjectTypes.MicrosoftVisualStudioScrum10:
          reportTemplate = new MicrosoftVisualStudioScrum10Template();
          break;
        case ProjectTypes.MSFforAgileSoftwareDevelopmentv50:
          reportTemplate = new MSFforAgileSoftwareDevelopmentv50Template();
          break;
        default:
          MessageBox.Show("Supported process templates:\nMicrosoft Visual Studio Scrum 1.0\nMSF for Agile Software Development v5.0", "Error");
          return false;
      }

      var data = listView.SelectedItems.Cast<WorkItem>().ToList();
      var report = reportTemplate.Create(data);

      using (var package = Package.Open(path, FileMode.Create))
      {
        var document = new XpsDocument(package);

        var writer = XpsDocument.CreateXpsDocumentWriter(document);
        writer.Write(report.DocumentPaginator);

        document.Close();
      }
      return true;
    }

    private void generateReport_Click(object sender, RoutedEventArgs e)
    {
      if (projInfo == null)
        return;

      // Create report
      var path = Path.GetTempFileName();
      if (GenerateAndSaveReport(path) == false)
      {
        MessageBox.Show("Unable to create report!", "Error");
        return;
      }
      var document = new XpsDocument(path, FileAccess.Read);

      // Create tab
      var tab = new TabItem {Header = "Report @ " + DateTime.Now.ToLongTimeString()};
      var doc = new DocumentViewer {Document = document.GetFixedDocumentSequence()};
      doc.FitToMaxPagesAcross(1);
      tab.Content = doc;
      tabControl.Items.Insert(1, tab);
      tabControl.SelectedItem = tab;
    }

    private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
    {
      System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(e.Uri.AbsoluteUri));
      e.Handled = true;
    }
  }
}